using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.Runtime.Serialization;
using System.Windows.Forms;

namespace CartoGraphic.Model2
{
	/// <summary>
	/// List of graphic objects
	/// </summary>
	[Serializable]
	public class GraphicsList
	{
		private ArrayList graphicsList;

		private bool _isDirty;

		public bool Dirty
		{
			get
			{
				if (_isDirty == false)
				{
					foreach (BaseDrawingObj o in graphicsList)
					{
						if (o.Dirty)
						{
							_isDirty = true;
							break;
						}
					}
				}
				return _isDirty;
			}
			set
			{
				foreach (BaseDrawingObj o in graphicsList)
					o.Dirty = false;
				_isDirty = false;
			}
		}

		public IEnumerable<BaseDrawingObj> Selection
		{
			get
			{
				foreach (BaseDrawingObj o in graphicsList)
				{
					if (o.Selected)
					{
						yield return o;
					}
				}
			}
		}

		private const string entryCount = "ObjectCount";
		private const string entryType = "ObjectType";

		public GraphicsList()
		{
			graphicsList = new ArrayList();
		}

		public void LoadFromStream(SerializationInfo info, int orderNumber)
		{
			
		}

		public void SaveToStream(SerializationInfo info, int orderNumber)
		{
			
		}

		public void Draw(Graphics g,GraphicsProperties gps)
		{
			int numberObjects = graphicsList.Count;

			for (int i = numberObjects - 1; i >= 0; i--)
			{
				BaseDrawingObj o;
				o = (BaseDrawingObj)graphicsList[i];
				if (o.IntersectsWith(Rectangle.Round(g.ClipBounds)))
					o.Draw(g,gps);
				if (o.Selected)
					o.DrawTracker(g);
			}
		}

		public bool Clear()
		{
			bool result = (graphicsList.Count > 0);
			graphicsList.Clear();
			if (result)
				_isDirty = false;
			return result;
		}

		public int Count
		{
			get { return graphicsList.Count; }
		}

		public BaseDrawingObj this[int index]
		{
			get
			{
				if (index < 0 ||
				    index >= graphicsList.Count)
					return null;

				return (BaseDrawingObj)graphicsList[index];
			}
		}

		public int SelectionCount
		{
			get
			{
				int n = 0;

				foreach (BaseDrawingObj o in graphicsList)
				{
					if (o.Selected)
						n++;
				}

				return n;
			}
		}

		public BaseDrawingObj GetSelectedObject(int index)
		{
			int n = -1;

			foreach (BaseDrawingObj o in graphicsList)
			{
				if (o.Selected)
				{
					n++;

					if (n == index)
						return o;
				}
			}

			return null;
		}

		public void Add(BaseDrawingObj obj)
		{
			graphicsList.Sort();
			foreach (BaseDrawingObj o in graphicsList)
				o.ZOrder++;

			graphicsList.Insert(0, obj);
		}

		public void SelectInRectangle(Rectangle rectangle)
		{
			UnselectAll();

			foreach (BaseDrawingObj o in graphicsList)
			{
				if (o.IntersectsWith(rectangle))
					o.Selected = true;
			}
		}

		public void UnselectAll()
		{
			foreach (BaseDrawingObj o in graphicsList)
			{
				o.Selected = false;
			}
		}

		public void SelectAll()
		{
			foreach (BaseDrawingObj o in graphicsList)
			{
				o.Selected = true;
			}
		}

		public bool DeleteSelection()
		{
			bool result = false;

			int n = graphicsList.Count;

			for (int i = n - 1; i >= 0; i--)
			{
				if (((BaseDrawingObj)graphicsList[i]).Selected)
				{
					graphicsList.RemoveAt(i);
					result = true;
				}
			}
			if (result)
				_isDirty = true;
			return result;
		}


		public void DeleteLastAddedObject()
		{
			if (graphicsList.Count > 0)
			{
				graphicsList.RemoveAt(0);
			}
		}

		public void Replace(int index, BaseDrawingObj obj)
		{
			if (index >= 0 &&
			    index < graphicsList.Count)
			{
				graphicsList.RemoveAt(index);
				graphicsList.Insert(index, obj);
			}
		}

		public void RemoveAt(int index)
		{
			graphicsList.RemoveAt(index);
		}


		public bool MoveSelectionToFront()
		{
			int n;
			int i;
			ArrayList tempList;

			tempList = new ArrayList();
			n = graphicsList.Count;

			for (i = n - 1; i >= 0; i--)
			{
				if (((BaseDrawingObj)graphicsList[i]).Selected)
				{
					tempList.Add(graphicsList[i]);
					graphicsList.RemoveAt(i);
				}
			}

			n = tempList.Count;

			for (i = 0; i < n; i++)
			{
				graphicsList.Insert(0, tempList[i]);
			}
			if (n > 0)
				_isDirty = true;
			return (n > 0);
		}

		public bool MoveSelectionToBack()
		{
			int n;
			int i;
			ArrayList tempList;

			tempList = new ArrayList();
			n = graphicsList.Count;

			for (i = n - 1; i >= 0; i--)
			{
				if (((BaseDrawingObj)graphicsList[i]).Selected)
				{
					tempList.Add(graphicsList[i]);
					graphicsList.RemoveAt(i);
				}
			}

			n = tempList.Count;

			for (i = n - 1; i >= 0; i--)
			{
				graphicsList.Add(tempList[i]);
			}
			if (n > 0)
				_isDirty = true;
			return (n > 0);
		}

		private GraphicsProperties GetProperties()
		{
			GraphicsProperties properties = new GraphicsProperties();

			//int n = SelectionCount;

			//if (n < 1)
			//    return properties;

			//BaseDrawingObj o = GetSelectedObject(0);

			//int firstColor = o.Color.ToArgb();
			//int firstPenWidth = o.PenWidth;

			//bool allColorsAreEqual = true;
			//bool allWidthAreEqual = true;

			//for (int i = 1; i < n; i++)
			//{
			//    if (GetSelectedObject(i).Color.ToArgb() != firstColor)
			//        allColorsAreEqual = false;

			//    if (GetSelectedObject(i).PenWidth != firstPenWidth)
			//        allWidthAreEqual = false;
			//}

			//if (allColorsAreEqual)
			//{
			//    properties.ColorDefined = true;
			//    properties.Color = Color.FromArgb(firstColor);
			//}

			//if (allWidthAreEqual)
			//{
			//    properties.PenWidthDefined = true;
			//    properties.PenWidth = firstPenWidth;
			//}

			return properties;
		}

		private void ApplyProperties()
		{
            //foreach (BaseDrawingObj o in graphicsList)
            //{
            //    if (o.Selected)
            //    {
            //        if (properties.ColorDefined)
            //        {
            //            o.Color = properties.Color;
            //            BaseDrawingObj.LastUsedColor = properties.Color;
            //        }

            //        if (properties.PenWidthDefined)
            //        {
            //            o.PenWidth = properties.PenWidth;
            //            BaseDrawingObj.LastUsedPenWidth = properties.PenWidth;
            //        }
            //    }
            //}
		}

		public bool ShowPropertiesDialog(IWin32Window parent)
		{
			return true;
		}
	}
}